// import { IYieldWrapper, YieldWrapper } from "./Coroutine";
// import { GameTime } from "./GameTime";

const ccmath = (cc as any).math;
export const randomRangeInt = ccmath.randomRangeInt;
export const randomRange = ccmath.randomRange;

/** map */
const tempV2 = cc.v2();
/** 返回子节点在父节点中的坐标 */
export function convertPosition(child: cc.Node, parent: cc.Node, out?: cc.Vec2): cc.Vec2 {
    const out0 = out ? out : cc.v2();
    child.convertToWorldSpaceAR(cc.Vec2.ZERO, tempV2);
    parent.convertToNodeSpaceAR(tempV2, out0);
    return out0;
}

export const ArrayUtils = {
    Count<T>(array: Array<T>, check: (a: T) => boolean): number {
        let n = 0;
        for (const iterator of array) {
            if (check(iterator)) n++;
        }
        return n;
    },
    Remove<T>(array: Array<T>, element: T): boolean {
        const index = array.indexOf(element);
        if (index >= 0) {
            array.splice(index, 1);
            return true;
        }
        return false;
    },
    ToMap<T>(array: Array<T>, getkey: (arg: T) => string, out?: { [key: string]: T }): { [key: string]: T } {
        const _out: { [key: string]: T } = out || {};
        // eslint-disable-next-line no-return-assign
        array.forEach((it) => (_out[getkey(it)] = it));
        return _out;
    },
    Flat<T, U>(array: Array<T>, action: (arg: T) => U): Array<U> {
        const newArr = [];
        array.forEach((it) => newArr.push(action(it)));
        return newArr;
    },
    FindFirst<T>(array: Array<T>, action: (arg: T) => boolean): T {
        // eslint-disable-next-line @typescript-eslint/prefer-for-of
        for (let i = 0; i < array.length; i++) {
            const element = array[i];
            if (action(element)) return element;
        }
        return null;
    },
    FindLast<T>(array: Array<T>, action: (arg: T) => boolean): T {
        for (let i = array.length - 1; i >= 0; i--) {
            const element = array[i];
            if (action(element)) return element;
        }
        return null;
    },
    Shuffle(array: Array<any>) {
        let index = -1;
        let length = array.length;
        let lastIndex = length - 1;
        let size = length;
        while (++index < size) {
            const rand = index + Math.floor(Math.random() * (lastIndex - index + 1));
            const value = array[rand];
            array[rand] = array[index];
            array[index] = value;
        }
    },
    ShuffleArray(array: Array<any>) {
        array.sort(() => Math.random() - 0.5);
    },
};

/** 延迟duration秒后返回true, 否则返回false, 需要每帧调用 */
export function MkDelay(duration: number, getDeltaTime: () => number) {
    let _elaspedTime = 0;
    return () => {
        _elaspedTime += getDeltaTime();
        return _elaspedTime > duration;
    };
}

/** 延迟并缓存获取某个值 */
export function LazyCacheGetter<T>(getter: () => T) {
    let _value = null;
    return (): T => {
        if (!_value) _value = getter();
        return _value;
    };
}

// //#region  协程方法
// export class GameWaitForSecond extends YieldWrapper {
//     private eslapedTime: number = 0;
//     get finished(): boolean {
//         this.eslapedTime += GameTime.deltaTime;
//         return this.eslapedTime >= this.duration;
//     }
//     constructor(private duration: number) { super(); }
// }

// export class GameWaitForRealTime extends YieldWrapper {
//     private eslapedTime: number = 0;
//     get finished(): boolean {
//         this.eslapedTime += GameTime.unscaledDeltaTime;
//         return this.eslapedTime >= this.duration;
//     }
//     constructor(private duration: number) { super(); }
// }
// //#endregion

window["randomRangeInt"] = randomRangeInt;
window["randomRange"] = randomRange;